/**
	Constructs a 

	@author Matthew Richmond
	@version 2006-11-02

	@usage

	- Activate with:
	<code>

	import timber.ui.ToolTipController;
	import timber.ui.ToolTipDefaultView; // optional if you are using your own ToolTip class
	
	// create our singleton instance
	toolTip = ToolTipController.getInstance();
	// if you dont supply a second argument, the ToolTipController uses the default ToolTipDefault
	ToolTipController.init(this, new ToolTipDemoView() );
	// specify the horozontal offset in pixels for the tooltip relative to the mouse
	ToolTipController.setOffsetX(8);
	// specify the vertical offset in pixels for the tooltip relative to the mouse
	ToolTipController.setOffsetY(4);
	
	// to add a tooltip to an object
	
	clip.onRollOver = function (){
		ToolTipController.create( this, "top", "center", clip.colorid );
	};
	
	clip.onRollOut = function (){
		ToolTipController.destroy();
	};

	</code>

*/
import timber.ui.ToolTipDefaultView;
import mx.transitions.Tween;
import mx.transitions.easing.*;
import mx.utils.Delegate;

class timber.ui.ToolTipController {

	private static var _instance = null;			//singleton
	private var obj:MovieClip;						//main clip where mouse position is tracked

	private var targ:MovieClip;						//where tooltips are created

	private var xchoice:String;						//x position of tooltip
	private var ychoice:String;						//y position of tooltip
	private var msg:String;							//tooltip message
	
	private var offsetX:Number = 0;					//horozontal offset in pixels for the tooltip relative to the mouse
	private var offsetY:Number = 0;					//vertical offset in pixels for the tooltip relative to the mouse
	
	private var tipView;							//view class for tooltip
	
	private var tip:MovieClip;						//tooltip class
					
	private var tipTimer:Number;					//timer for tip display
	
	private var horozontalEdgeBuffer:Number	= 4;	//amount in pixels horozontal buffer

	private var tipFade:Boolean = false;			//boolean switch for tip fade
	private var tipFadeSpeed:Number = .25;			//tip fade speed

// ===========================================================
// - CONSTRUCTOR
// ===========================================================

	/**
	Constructor
	*/
	private function ToolTipController () {
		//trace("ToolTipController");
		
		this.obj = _root; 
	};

// ===========================================================
// - GET SINGLETON INSTANCE
// ===========================================================
	/**
	Singleton Init
	*/
	public static function getInstance() {
		if (_instance == null) {
			ToolTipController._instance = new ToolTipController();
		};
		return ToolTipController._instance;
	};

// ===========================================================
// - INIT
// ===========================================================

	/**
	Inatilizes the the ToolTipController, gets it ready to work

	@param	obj	MovieClip location that the Controller uses to do the mouse calculations
	@param	view	View object that creates the ToolTip itself, if empty the Controller will use ToolTipDefaultView
	*/
	public static function init (obj:MovieClip, view){
		//trace("ToolTipController: init");
		var ttc = ToolTipController.getInstance();
		
		ttc.obj = obj;
		
		if (!view) {
			ttc.tipView = new ToolTipDefaultView();
		} else {
			ttc.tipView = view;
		}
	};

// ===========================================================
// - ACCESSORS
// ===========================================================

	/**
	Horozontal offset in pixels for the tooltip relative to the mouse

	@param	val Number in pixels
	*/
	public static function setOffsetX (val:Number){
		//trace("ToolTipController: setOffsetX");
		var ttc = ToolTipController.getInstance();
		
		ttc.offsetX = val;
	};

	/**
	Vertical offset in pixels for the tooltip relative to the mouse

	@param	val Number in pixels
	*/
	public static function setOffsetY (val:Number){
		//trace("ToolTipController: setOffsetY");
		var ttc = ToolTipController.getInstance();
		
		ttc.offsetY = val;
	};
	
	/**
	Number in pixels for the horizontal edge buffer, if a tooltip is within the buffer or off the edge it will be automatically moved inside the buffer.

	@param	val Number in pixels
	*/
	public static function setHorozontalEdgeBuffer (val:Number){
		//trace("ToolTipController: setHorozontalEdgeBuffer");
		var ttc = ToolTipController.getInstance();
		
		ttc.horozontalEdgeBuffer = val;
	};
	
	/**
	Boolean switch to turn tooltip fade on and off.

	@param	val Boolean
	*/
	public static function setTipFade (val:Boolean){
		//trace("ToolTipController: setTipFade");
		var ttc = ToolTipController.getInstance();
		
		ttc.tipFade = val;
	};
	
	/**
	Number in seconds of the tooltip fade.

	@param	val Number in seconds
	*/
	public static function setTipFadeSpeed (val:Number){
		//trace("ToolTipController: setTipFadeSpeed");
		var ttc = ToolTipController.getInstance();
		
		ttc.tipFadeSpeed = val;
	};

// ===========================================================
// - CREATE TIP
// ===========================================================

	public static function create (targ:MovieClip, ychoice:String, xchoice:String, msg:String){
		//trace("ToolTipController: create: msg="+msg);
		var ttc = ToolTipController.getInstance();
		
		ttc.targ = targ;
		ttc.xchoice = xchoice;
		ttc.ychoice = ychoice;
		ttc.msg = msg;
	
		ttc.startTimer ();
	};

	function create2 (){
		//trace("ToolTipController: create2");
		var ttc = ToolTipController.getInstance();
		
		ttc.stopTimer ();
		
		ttc.makeTip ();
		ttc.hideTip ();
		ttc.positionTip ();
		ttc.revealTip();
		
	};

	function makeTip (){
		//trace("ToolTipController: makeTip");
		var ttc = ToolTipController.getInstance();
		
		tip = ttc.tipView.create(ttc.targ, ttc.msg);
	};

	function hideTip (){
		//trace("ToolTipController: hideTip");
		var ttc = ToolTipController.getInstance();
		
		ttc.tip._alpha = 0;
	};

	function positionTip (){
		//trace("ToolTipController: positionTip");
		var ttc = ToolTipController.getInstance();
		
		var newx:Number;
		var newy:Number;
		
		var targx:Number = ttc.targ._x;
		var targy:Number = ttc.targ._y;
				
		var p:Object = {x:targx, y:targy};
		ttc.targ.localToGlobal(p)
		
		// position left / right
		switch ( ttc.xchoice.toLowerCase() ) {
			case "center" : 
				newx = ttc.checkHorozontalEdge( ttc.obj._xmouse - (ttc.tip._width * .5) + ttc.offsetX );
				break;
			case "left" : 
				newx = ttc.checkHorozontalEdge( ttc.obj._xmouse - ttc.tip._width + ttc.offsetX );
				break;
			case "right":
				newx = ttc.checkHorozontalEdge( ttc.obj._xmouse - ttc.offsetX );
				break;
		}
		
		// position top bottom
		switch ( ttc.ychoice.toLowerCase() ) {
			case "center" : 
				newy = ttc.obj._ymouse - (ttc.tip._height * .5) - ttc.offsetY;
				break;
			case "top" : 
				newy = ttc.obj._ymouse - ttc.tip._height - ttc.offsetY;
				break;
			case "bottom":
				newy = ttc.obj._ymouse + ttc.offsetY;
				break;
		}
				
		ttc.tip._x = newx;
		ttc.tip._y = newy;
	};

	function checkHorozontalEdge (val:Number):Number{
		//trace("ToolTipController: checkHorozontalEdge");
		var ttc = ToolTipController.getInstance();
		
		var targw:Number = ttc.targ._width;
		var targh:Number = ttc.targ._height;
		
		// corret for hanging off the left
		if ( val < (0 + ttc.horozontalEdgeBuffer) ) {
			return ttc.horozontalEdgeBuffer;
		}
		
		// corret for hanging off the right
		if ( (val + ttc.tip._width) > (Stage.width - ttc.horozontalEdgeBuffer) ) {
			return Stage.width - ttc.horozontalEdgeBuffer - ttc.tip._width;
		}
		
		return val;
	};

	function revealTip (){
		//trace("ToolTipController: revealTip");
		var ttc = ToolTipController.getInstance();
		
		if (ttc.tipFade) {
			new Tween(ttc.tip, "_alpha", Regular.easeIn, 0, 100, ttc.tipFadeSpeed, true);
		} else {
			ttc.tip._alpha = 100;
		}

	};

	public static function destroy (){
		//trace("ToolTipController: destroy");
		var ttc = ToolTipController.getInstance();
		
		ttc.stopTimer ();
		
		removeMovieClip (ttc.tip);
	};

	function startTimer (){
		//trace("ToolTipController: startTimer");
		var ttc = ToolTipController.getInstance();
		
		ttc.tipTimer = setInterval(Delegate.create(ttc, create2), 500)
	};

	function stopTimer (){
		//trace("ToolTipController: stopTimer");
		var ttc = ToolTipController.getInstance();
		
		clearInterval(ttc.tipTimer);
	};
};